import threading
import time
import os
import requests
import socket
import json
from datetime import datetime, timedelta, timezone
from netease import NetEase
from pathlib import Path
from param import *
from publib import setup_logger, get_logger, csv_read_list, csv_write_list

cur_file = os.path.basename(__file__).split(".")[0]
logger = get_logger(__name__)

config = []
if (os.path.exists("config.json")):
    with open("config.json", "r") as f:
        config = json.load(f)

upgrade_task_thread = None
app_task_id = None

def push_msg(title, msg):
    push_token = config.get("push", {}).get("token", None)
    push_id = config.get("push", {}).get("id", None)
    try:
        body = {"token": push_token, "service_id": push_id,"title":title,"content":msg}
        r = requests.post("https://tui.juhe.cn/api/plus/pushApi", data=body).json()
        logger.info(f"push msg: {title} {msg}, result: {r.get('reason')}")
    except:
        logger.info(f"failed to push msg: {title} {msg}")
    
def get_update_period():
    t = 3600
    try:
        with open("update_ploy", "r") as f:
            t = int(f.read())
    except:
        pass
    return t

def check_app():
    logger.info("main check app")
    err = True
    try:
        r = requests.get(f"http://free.frp.vip:10074/app/hot_fm", timeout=5)
        logger.info(f"result {r.status_code}")
        if (r.status_code == 200):
            err = False
    except:
        logger.info("check app err")
        pass
    logger.info("check app end")

def get_netease_top_list():
    lrc = 'http://music.163.com/api/song/lyric?id='

    netease = NetEase()
    all_data = netease.top_songlist()
    csv_data = []

    # logger.info(all_data)

    for data in all_data:
        url = str(data['id'])
        lrc_url = lrc + str(data['id']) + '&lv=-1&kv=-1&tv=-1'
        pic_url = data["album"]["picUrl"]
        name = data['name']
        artist = data['artists'][0]['name']
        csv_data.append([name, artist, url, pic_url, lrc_url])

    return csv_data

def netease_list_update(file_out):
    logger.info(f"netease_list_update")
    music = get_netease_top_list()
    csv_write_list(file_out, music, "w")

def get_qqmusic_list():
    date = datetime.now().strftime('%Y-%m-%d')
    topId = 26
    url = f"https://u.y.qq.com/cgi-bin/musicu.fcg?g_tk=5381&data=%7B%22detail%22%3A%7B%22module%22%3A%22musicToplist.ToplistInfoServer%22%2C%22method%22%3A%22GetDetail%22%2C%22param%22%3A%7B%22topId%22%3A{topId}%2C%22offset%22%3A0%2C%22num%22%3A100%2C%22period%22%3A%22{date}%22%7D%7D%2C%22comm%22%3A%7B%22ct%22%3A24%2C%22cv%22%3A0%7D%7D"
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36',
    }
    # logger.info(url)
    r = requests.get(url, headers=headers)
    data = r.json()

    csv_data = []
    song = data["detail"]["data"]["songInfoList"]

    for i in song:
        name = i.get("title", "")
        artist = ""
        for s in i.get("singer", []):
            artist += s.get("name", "") + '/'
        artist = artist[:-1]
        songmid = i.get("mid", "")
        csv_data.append([name, artist, songmid])
    return csv_data

def tx_list_update(file_out):
    logger.info(f"tx_list_update")
    music = get_qqmusic_list()
    csv_write_list(file_out, music, "w")

def get_kwmusic_list(id):
    url = f"http://kbangserver.kuwo.cn/ksong.s?from=pc&fmt=json&pn=0&rn=500&type=bang&data=content&id={id}&show_copyright_off=0&pcmp4=1&isbang=1&userid=0&httpStatus=1"
    data = requests.get(url).json()

    csv_data = []
    song = data["musiclist"]

    for i in song:
        name = i.get("name", "")
        artist = i.get("artist", "")
        id = i.get("id", "")
        csv_data.append([name, artist, id])
    return csv_data

def kw_list_update(file_out):
    ids = [16, 26] # 热歌榜/经典怀旧榜
    logger.info(f"kw_list_update")
    music = []
    for id in ids:
        new = get_kwmusic_list(id)
        for n in new:
            if n not in music:
                music.append(n)
    csv_write_list(file_out, music, "w")

def get_kgmusic_list(id):
    url = f"http://mobilecdnbj.kugou.com/api/v3/rank/song?version=9108&ranktype=0&plat=0&pagesize=1000&area_code=1&page=1&volid=35050&rankid={id}&with_res_tag=0"
    data = requests.get(url).json()
    logger.info(data.get("total", 0))

    csv_data = []
    song = data.get("data", {}).get("info", [])

    for i in song:
        name = i.get("songname", "")
        artist = ""
        for s in i.get("authors", []):
            artist += s.get("author_name", "") + '/'
        artist = artist[:-1]
        id = i.get("hash", "")
        csv_data.append([name, artist, id])
    return csv_data

def kg_list_update(file_out):
    bang = {
        "酷狗TOP500": 8888,
        "80后热歌榜": 49225,
        "90后热歌榜": 49223,
    }
    logger.info(f"kg_list_update")
    music = []
    for id in bang:
        new = get_kgmusic_list(bang[id])
        for n in new:
            if n not in music:
                music.append(n)
    csv_write_list(file_out, music, "w")


def fm_get_cur_id_info_csv(id):
    music_infos = []
    r = requests.get(f"https://webapi.qingting.fm/api/pc/radio/{id}")
    data = r.json()
    yesterday = (datetime.now() - timedelta(days=1)).strftime('%Y%m%d')
    if (data["album"] == []):
        return []
    picurl = data["album"]["cover"]
    artistsname = data["album"]["title"]

    today = datetime.now().weekday()
    today = (today + 1) if (today + 1) <= 6 else 7  

    d_data = data["pList"][str(today)]
    for i in d_data:
        name = i["title"]
        start_time = i["start_time"].replace(":", "")
        end_time = i["end_time"].replace(":", "")
        url = f"http://lcache.qtfm.cn/cache/{yesterday}/{id}/{id}_{yesterday}_{start_time}_{end_time}_24_0.aac"
        music_infos.append([name,artistsname, url, picurl])
    return music_infos

def radio_list_update(file_in, file_out):
    logger.info(f"radio_list_update {file_in}")
    radios = []
    ids = csv_read_list(file_in)
    for id in ids:
        radios += fm_get_cur_id_info_csv(id[0])
    
    csv_write_list(file_out, radios, "w")

def update_audio_task():
    if not os.path.exists(FM_PLAYLIST_HOT):
        Path(FM_PLAYLIST_HOT).parent.mkdir(parents=True, exist_ok=True)
        radio_list_update(FM_HOT_ID, FM_PLAYLIST_HOT)
    if not os.path.exists(NETEASE_PLAYLIST_HOT):
        Path(NETEASE_PLAYLIST_HOT).parent.mkdir(parents=True, exist_ok=True)
        netease_list_update(NETEASE_PLAYLIST_HOT)
    if not os.path.exists(TX_PLAYLIST_HOT):
        Path(TX_PLAYLIST_HOT).parent.mkdir(parents=True, exist_ok=True)
        tx_list_update(TX_PLAYLIST_HOT)
    if not os.path.exists(KW_PLAYLIST_HOT):
        Path(KW_PLAYLIST_HOT).parent.mkdir(parents=True, exist_ok=True)
        tx_list_update(KW_PLAYLIST_HOT)
    if not os.path.exists(KG_PLAYLIST_HOT):
        Path(KG_PLAYLIST_HOT).parent.mkdir(parents=True, exist_ok=True)
        kg_list_update(KG_PLAYLIST_HOT)
    while (1):
        # 北京时间
        hour = (datetime.now(timezone.utc).hour + 8) % 24
        if (hour == 2):
            radio_list_update(FM_HOT_ID, FM_PLAYLIST_HOT)
            netease_list_update(NETEASE_PLAYLIST_HOT)
            tx_list_update(TX_PLAYLIST_HOT)
            kw_list_update(KW_PLAYLIST_HOT)
            kg_list_update(KG_PLAYLIST_HOT)
            time.sleep(3600 * 10)
        else:
            time.sleep(1800)

def check_remote_port(remote_host, port):
    ret = False
    try:
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.settimeout(2)
        result = sock.connect_ex((remote_host, port))
        if (result == 0):
            ret = True
    except socket.error as e:
        logger.info(f"Error occurred: {e}")
    finally:
        sock.close()
    logger.info(f"check remote port {remote_host}:{port} ret: {ret}")
    return ret

def check_frp():
    title = ""
    msg = ""
    fail_list = []
    for host, port in config.get("frp", []):
        if (check_remote_port(host, port) == False):
            fail_list.append(host)
    if (len(fail_list) > 0):
        title = "frp err"
        for _ in fail_list:
            msg += _ + '\n'
        push_msg(title, msg)
    else:
        logger.info("frp check ok")

def check_frp_task():
    while (1):
        hour = (datetime.now(timezone.utc).hour + 8) % 24
        if (hour == 6):
            check_frp()
            time.sleep(3600 * 10)
        else:
            time.sleep(1800)

def main_task():
    thread_list = []
    thread_list.append(threading.Thread(target=update_audio_task))
    thread_list.append(threading.Thread(target=check_frp_task))

    for t in thread_list:
        t.daemon = True
        t.start()

    try:
        while True:
            time.sleep(1)
    except KeyboardInterrupt:
        print("exit")

def __main__():
    setup_logger(f"logs/{cur_file}.log")
    main_task()
    logger.info("exit")

__main__()    
